﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Xml.Serialization;
using System.Xml;
using System.Web.Script.Serialization;

//using log4net;

namespace Common.Serialization
{

    /// <summary>
    /// 序列化帮助类
    /// </summary>
    public class SimpleSerialization
    {
       // private static readonly ILog logger = LogManager.GetLogger(typeof(SimpleSerialization));

        #region Multi Type
        public static string Serialize( object obj, SerializationType stype )
        {
            try
            {
                switch (stype)
                {
                    case SerializationType.None:
                        return obj.ToString();
                    case SerializationType.Json:
                        return obj.TOJSON();
                    case SerializationType.Xml:
                    default:
                        return ObjectToXml(obj);
                }
            }
            catch { 
                return string.Empty; 
            }
        }

        public static object Deserialize( string str, SerializationType stype )
        {
            try
            {
                switch (stype)
                {
                    case SerializationType.None:
                        return null;
                    case SerializationType.Json:
                        return JsonToObject(str);
                    case SerializationType.Xml:
                    default:
                        return ObjectToXml(str);
                }
            }
            catch {
                return new object();
            }
        }

        public static T Deserialize<T>( string str, SerializationType stype )
        {
            switch( stype )
            {
                case SerializationType.None:
                    return default(T);
                case SerializationType.Json:
                    return JsonToObject<T>( str );
                case SerializationType.Xml:
                default:
                    return XmlToObject<T>( str );
            }
        }
        #endregion

        #region Json
        /// <summary>
        /// 对象
        /// </summary>
        /// <param name="obj"></param>
        /// <returns></returns>
        public static string ObjectToJson(object obj)
        {
            JavaScriptSerializer Serializer = new JavaScriptSerializer();
            StringBuilder outJson = new StringBuilder();
            Serializer.Serialize(obj, outJson);
            return outJson.ToString();
        }

        /// <summary>
        /// 对象
        /// </summary>
        /// <param name="obj"></param>
        /// <returns></returns>
        public static object JsonToObject( string str )
        {
            JavaScriptSerializer Serializer = new JavaScriptSerializer();
            StringBuilder outJson = new StringBuilder();
            return Serializer.DeserializeObject( str );
        }

        /// <summary>
        /// 对象
        /// </summary>
        /// <param name="obj"></param>
        /// <returns></returns>
        public static T JsonToObject<T>( string str )
        {
            JavaScriptSerializer Serializer = new JavaScriptSerializer();
            StringBuilder outJson = new StringBuilder();
            return Serializer.Deserialize<T>( str );
        }
        #endregion

        #region Xml
        /// <summary>
        /// 对象序列化到XML
        /// </summary>
        /// <param name="obj"></param>
        /// <returns></returns>
        public static string ObjectToXml( object obj )
        {
            if( obj == null )
            {
                return string.Empty;
            }
            XmlWriterSettings setting = new XmlWriterSettings();
            setting.CheckCharacters = false;
            setting.Encoding = Encoding.UTF8;
            setting.Indent = true;

            System.Xml.Serialization.XmlSerializer ser = new System.Xml.Serialization.XmlSerializer( obj.GetType() );

            MemoryStream stream = new MemoryStream();
            using (XmlWriter writer = XmlWriter.Create(stream, setting))
            {
                ser.Serialize( writer, obj );
            }
                        
            stream.Position = 0;
            using( StreamReader sr = new StreamReader( stream ) )
            {
                return sr.ReadToEnd();
            }
        }

        /// <summary>
        /// XML反序列化回对象
        /// </summary>
        /// <param name="xml"></param>
        /// <param name="t"></param>
        /// <returns></returns>
        public static object XmlToObject( string xml, Type t )
        {
            if( xml == null || t == null )
            {
                return null;
            }
            System.Xml.Serialization.XmlSerializer ser = new System.Xml.Serialization.XmlSerializer( t );

            System.Xml.XmlDocument xdoc = new System.Xml.XmlDocument();
            xdoc.LoadXml( xml );
            object obj = null;
            using( System.Xml.XmlNodeReader reader = new System.Xml.XmlNodeReader( xdoc.DocumentElement ) )
            {
                obj = ser.Deserialize( reader );
            }
            return obj;
        }

        /// <summary>
        /// XML反序列化回对象
        /// </summary>
        /// <param name="xml"></param>
        /// <param name="t"></param>
        /// <returns></returns>
        public static T XmlToObject<T>( string xml )
        {
            if( xml == null )
            {
                return default(T);
            }
            System.Xml.Serialization.XmlSerializer ser = new System.Xml.Serialization.XmlSerializer( typeof( T ) );

            System.Xml.XmlDocument xdoc = new System.Xml.XmlDocument();
            xdoc.LoadXml( xml );
            object obj = null;
            using( System.Xml.XmlNodeReader reader = new System.Xml.XmlNodeReader( xdoc.DocumentElement ) )
            {
                obj = ser.Deserialize( reader );
            }
            return (T)obj;
        }
        #endregion

        #region Binary
        // Methods
        public static byte[] ToBytes( object value )
        {
            if( value == null )
            {
                return null;
            }
            using( MemoryStream stream = new MemoryStream() )
            {
                new System.Runtime.Serialization.Formatters.Binary.BinaryFormatter().Serialize( stream, value );
                return stream.ToArray();
            }
        }

        public static object ToObject( byte[] serializedObject )
        {
            if( serializedObject == null )
            {
                return null;
            }
            using( MemoryStream stream = new MemoryStream( serializedObject ) )
            {
                return new System.Runtime.Serialization.Formatters.Binary.BinaryFormatter().Deserialize( stream );
            }
        }
        #endregion 
    }
}
